namespace OneCaps.Core.Models
{
    /// <summary>
    /// 金额值对象
    /// </summary>
    public class Money
    {
        /// <summary>
        /// 金额（元）
        /// </summary>
        public decimal Amount { get; }

        /// <summary>
        /// 货币单位
        /// </summary>
        public string Currency { get; } = "CNY";

        public Money(decimal amount, string currency = "CNY")
        {
            if (amount < 0)
            {
                throw new ArgumentException("金额不能为负数", nameof(amount));
            }

            Amount = Math.Round(amount, 2, MidpointRounding.AwayFromZero);
            Currency = currency;
        }

        // 运算符重载
        public static Money operator +(Money left, Money right)
        {
            if (left.Currency != right.Currency)
            {
                throw new InvalidOperationException("不同货币不能相加");
            }
            return new Money(left.Amount + right.Amount, left.Currency);
        }

        public static Money operator -(Money left, Money right)
        {
            if (left.Currency != right.Currency)
            {
                throw new InvalidOperationException("不同货币不能相减");
            }
            return new Money(left.Amount - right.Amount, left.Currency);
        }

        public static Money operator *(Money money, decimal multiplier)
        {
            return new Money(money.Amount * multiplier, money.Currency);
        }

        public static Money operator *(decimal multiplier, Money money)
        {
            return money * multiplier;
        }

        public static bool operator ==(Money left, Money right)
        {
            return left.Equals(right);
        }

        public static bool operator !=(Money left, Money right)
        {
            return !left.Equals(right);
        }

        public static bool operator <(Money left, Money right)
        {
            if (left.Currency != right.Currency)
            {
                throw new InvalidOperationException("不同货币不能比较");
            }
            return left.Amount < right.Amount;
        }

        public static bool operator >(Money left, Money right)
        {
            if (left.Currency != right.Currency)
            {
                throw new InvalidOperationException("不同货币不能比较");
            }
            return left.Amount > right.Amount;
        }

        public static bool operator <=(Money left, Money right)
        {
            return left < right || left == right;
        }

        public static bool operator >=(Money left, Money right)
        {
            return left > right || left == right;
        }

        // 重写方法
        public override bool Equals(object? obj)
        {
            if (obj is not Money other)
                return false;

            return Amount == other.Amount && Currency == other.Currency;
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(Amount, Currency);
        }

        public override string ToString()
        {
            return $"{Amount:F2} {Currency}";
        }

        // 静态方法
        public static Money Zero(string currency = "CNY")
        {
            return new Money(0, currency);
        }

        /// <summary>
        /// 格式化显示
        /// </summary>
        public string ToDisplayString()
        {
            return Currency switch
            {
                "CNY" => $"¥{Amount:F2}",
                "USD" => $"${Amount:F2}",
                "EUR" => $"€{Amount:F2}",
                _ => ToString()
            };
        }
    }
} 